﻿using System.Data;

namespace Agile.Infra.Repository;

public interface IBaseRepository<TEntity> where TEntity : BaseModel
{
    SqlSugarScope Db { get; }

    #region 新增

    Task<int> AddAsync(TEntity model);
    Task<int> AddAsync(TEntity entity, Expression<Func<TEntity, object>> insertColumns = null);
    Task<int> AddAsync(List<TEntity> listEntity);

    void AddQueue(TEntity entity);
    void AddQueue(TEntity entity, Expression<Func<TEntity, object>> insertColumns = null);
    void AddQueue(List<TEntity> listEntity);

    #endregion

    #region 删除

    Task<bool> DeleteByIdAsync(object id);
    Task<bool> DeleteAsync(TEntity model);
    Task<bool> DeleteByIdsAsync(params object[] ids);
    Task<bool> DeleteAsync(Expression<Func<TEntity, bool>> whereExpression);

    void DeleteQueue(TEntity entity);
    void DeleteQueue(object id);
    void DeleteQueue(params object[] ids);
    void DeleteQueue(Expression<Func<TEntity, bool>> whereExpression);

    #endregion

    #region 修改

    Task<bool> UpdateAsync(TEntity model);
    Task<bool> UpdateAsync(TEntity entity, Expression<Func<TEntity, object>> columnsExpression = null, Expression<Func<TEntity, object>> ignoreColumnsExpression = null, Expression<Func<TEntity, bool>> whereExpression = null);
    Task<bool> UpdateAsync(Expression<Func<TEntity, TEntity>> columns, Expression<Func<TEntity, bool>> whereExpression);
    Task<bool> UpdateWithChangedAsync(TEntity entity, Expression<Func<TEntity, bool>> whereExpression = null, Expression<Func<TEntity, object>> ignoreColumnsExpression = null);


    void UpdateQueue(TEntity entity);
    void UpdateQueue(TEntity entity, Expression<Func<TEntity, object>> columnsExpression = null, Expression<Func<TEntity, object>> ignoreColumnsExpression = null, Expression<Func<TEntity, bool>> whereExpression = null);
    void UpdateQueue(Expression<Func<TEntity, TEntity>> columns, Expression<Func<TEntity, bool>> whereExpression);
    void UpdateWithChangedQueue(TEntity entity, Expression<Func<TEntity, bool>> whereExpression = null, Expression<Func<TEntity, object>> ignoreColumnsExpression = null);

    #endregion

    #region 查询

    #region Any、Max、Sum、Count
    Task<bool> AnyAsync(Expression<Func<TEntity, bool>> expression);

    Task<TResult> MaxAsync<TResult>(Expression<Func<TEntity, TResult>> columnExpression);

    Task<TResult> MaxAsync<TResult>(Expression<Func<TEntity, TResult>> columnExpression, Expression<Func<TEntity, bool>> whereExpression);

    Task<TResult> SumAsync<TResult>(Expression<Func<TEntity, TResult>> columnExpression);

    Task<TResult> SumAsync<TResult>(Expression<Func<TEntity, TResult>> columnExpression, Expression<Func<TEntity, bool>> whereExpression);

    Task<int> CountAsync(Expression<Func<TEntity, bool>> whereExpression);

    #endregion

    #region Get

    Task<TEntity> GetAsync(object objId);
    Task<TEntity> GetAsync(object objId, bool blnUseCache = false);
    Task<TEntity> GetAsync(Expression<Func<TEntity, bool>> whereExpression);
    Task<TResult> GetAsync<TResult>(Expression<Func<TEntity, TResult>> columnExpression, Expression<Func<TEntity, bool>> whereExpression);
    Task<TEntity> GetCheckAsync(object objId, string throwMessage = "数据不存在或已被删除");
    Task<TEntity> GetCheckAsync(Expression<Func<TEntity, bool>> whereExpression, string throwMessage = "数据不存在或已被删除");
    Task<TEntity> GetFirstAsync(Expression<Func<TEntity, bool>> whereExpression);
    Task<TEntity> GetFirstAsync(Expression<Func<TEntity, bool>> whereExpression, Expression<Func<TEntity, object>> orderByExpression, bool isAsc = true);

    #endregion

    #region List

    Task<List<TEntity>> QueryAsync();
    Task<List<TEntity>> QueryAsync(params object[] lstIds);
    Task<List<TEntity>> QueryAsync(Expression<Func<TEntity, bool>> whereExpression);
    Task<List<TEntity>> QueryAsync(Expression<Func<TEntity, bool>> whereExpression, Expression<Func<TEntity, object>> orderByExpression, bool isAsc = true);
    Task<List<TEntity>> QueryAsync(Expression<Func<TEntity, bool>> whereExpression, Expression<Func<TEntity, object>> orderByExpression, bool isAsc = true, int intTop = 10);
    Task<List<TEntity>> QueryAsync(Expression<Func<TEntity, TEntity>> columnExpression, Expression<Func<TEntity, bool>> whereExpression);
    Task<List<TEntity>> QueryAsync(Expression<Func<TEntity, TEntity>> columnExpression, Expression<Func<TEntity, bool>> whereExpression, Expression<Func<TEntity, object>> orderByExpression, bool isAsc = true);

    Task<List<TResult>> QueryAsync<TResult>(Expression<Func<TEntity, TResult>> columnExpression);
    Task<List<TResult>> QueryAsync<TResult>(Expression<Func<TEntity, TResult>> columnExpression, Expression<Func<TEntity, bool>> whereExpression);
    Task<List<TResult>> QueryAsync<TResult>(Expression<Func<TEntity, TResult>> columnExpression, Expression<Func<TEntity, bool>> whereExpression, Expression<Func<TEntity, object>> orderByExpression, bool isAsc = true);

    #endregion

    #region Mapping

    Task MappingAsync<T>(T entity, Func<T, long> getIDFun, Action<T, TEntity> mappingAction) where T : class;
    Task MappingAsync<T>(IList<T> list, Func<T, long> getIDFun, Action<T, TEntity> mappingAction) where T : class;

    Task MappingAsync<T>(T entity, Func<T, IEnumerable<long>> getIDFun, Action<T, IEnumerable<TEntity>> mappingAction) where T : class;
    Task MappingAsync<T>(IList<T> list, Func<T, IEnumerable<long>> getIDFun, Action<T, IEnumerable<TEntity>> mappingAction) where T : class;

    Task MappingAsync<T>(T entity, Func<T, long?> getIDFun, Action<T, TEntity> mappingAction) where T : class;
    Task MappingAsync<T>(IList<T> list, Func<T, long?> getIDFun, Action<T, TEntity> mappingAction) where T : class;

    Task MappingAsync<T>(T entity, Func<T, IEnumerable<long?>> getIDFun, Action<T, IEnumerable<TEntity>> mappingAction) where T : class;
    Task MappingAsync<T>(IList<T> list, Func<T, IEnumerable<long?>> getIDFun, Action<T, IEnumerable<TEntity>> mappingAction) where T : class;

    Task MappingAsync<T>(T entity, Func<T, string> getIDFun, Action<T, TEntity> mappingAction) where T : class;
    Task MappingAsync<T>(IList<T> list, Func<T, string> getIDFun, Action<T, TEntity> mappingAction) where T : class;

    Task MappingAsync<T>(T entity, Func<T, IEnumerable<string>> getIDFun, Action<T, IEnumerable<TEntity>> mappingAction) where T : class;
    Task MappingAsync<T>(IList<T> list, Func<T, IEnumerable<string>> getIDFun, Action<T, IEnumerable<TEntity>> mappingAction) where T : class;

    #endregion

    #region sql query
    Task<List<T>> QuerySqlAsync<T>(string strSql, params SugarParameter[] parameters) where T : new();
    #endregion

    #region DataTable
    Task<DataTable> QueryTableAsync(string strSql, params SugarParameter[] parameters);
    #endregion

    #endregion

    Task<int> SaveQueuesAsync(bool isTran = true);
}
